
#ifndef VEC1D_H
#define VEC1D_H
// 与标准库vector最大的不同是元素数目固定
// 数据最好声明为私有的，提供接口
// 在类内部可以直接访问私有数据
// 提供好的接口，不依赖实现（随着认知提升可以修改实现）
// 多维数组获取行的实现可以重载函数调用运算符，
// 如 a(:,4) ：用char 代表，就是麻烦一些, 但返回类型是什么呢？
#include <cstring>
#include <cassert>
template <typename T>
struct vec1d
{
    // using size_t = unsigned int;
    using iter = T *;
    using const_iter = const T *;

    vec1d() noexcept = default;
    explicit vec1d(size_t n) : sz{n}, elem{new T[n]} {}

    vec1d(const vec1d &);
    vec1d &operator=(const vec1d &);

    vec1d(vec1d &&) noexcept;
    vec1d &operator=(vec1d &&) noexcept;
    ~vec1d() { delete[] elem; }

    // 不返回 T 考虑到对象的大小
    const T &operator[](size_t n) const
    {
        assert(n < sz);
        return elem[n];
    }
    T &operator[](size_t n)
    {
        assert(n < sz);
        return elem[n];
    }
    T &operator()(size_t n)
    {
        assert(n < sz);
        return elem[n];
    }
    const T &operator()(size_t n) const
    {
        assert(n < sz);
        return elem[n];
    }

    template <typename C>
    vec1d &operator=(C a);
    inline void resize(size_t n) noexcept;

    iter begin() noexcept { return elem; }
    const_iter begin() const noexcept { return elem; }
    iter end() noexcept { return elem + sz; }
    const_iter end() const noexcept { return elem + sz; }
    size_t size() const noexcept { return sz; }

  private:
    void copy_from(const vec1d &src);
    void move_from(vec1d &src); // 引用的引用 没问题
    T *elem{nullptr};
    size_t sz{0};
};

template <typename T>
void vec1d<T>::copy_from(const vec1d &src)
{ // 调用函数检查为空
    sz = src.sz;
    elem = new T[sz];
    memcpy(elem, src.begin(), sizeof(T) * sz);
}

template <typename T>
void vec1d<T>::move_from(vec1d &src)
{ // 调用函数检查为空
    sz = src.sz;
    elem = src.elem;
    src.elem = nullptr;
    src.sz = 0;
}

template <typename T>
vec1d<T>::vec1d(const vec1d &src)
{ //只存数值，不存指针
    copy_from(src);
}

template <typename T>
vec1d<T> &vec1d<T>::operator=(const vec1d &src)
{
    if (this == &src)
        return *this;
    if (!elem)
        delete[] elem;
    copy_from(src);
    return *this;
}

template <typename T>
vec1d<T>::vec1d(vec1d &&src) noexcept
{
    move_from(src);
}

template <typename T>
vec1d<T> &vec1d<T>::operator=(vec1d &&src) noexcept
{
    if (this == &src)
        return *this;
    if (!elem)
        delete[] elem;
    move_from(src);
    return *this;
}

template <typename T>
template <typename C>
vec1d<T> &vec1d<T>::operator=(C a)
{
    if (elem)
    {
        for (size_t i = 0; i < sz; ++i)
            elem[i] = a;
    }
    return *this;
}

template <typename T> 
void vec1d<T>::resize(size_t n) noexcept
{
    // delete nullptr 什么也不做
    delete [] elem;
    elem = new T[n];
    sz = n;
}
#endif